<template>
  <div ref="cvsContainer" class="cvs-container">
    <div v-show="pageData.pointerShow" :style="`left:${pageData.pointerX - 15}px;`"
         class="ver_line"></div>
    <div v-show="pageData.pointerShow"
         :style="`top:${pageData.pointerY - 15}px;`"
         class="hor_line"></div>
    <canvas id="cvs" ref="cvs" class="canvas"></canvas>
    <div v-show="pageData.pointerShow" :style="`left:${pageData.pointerX}px;top: ${pageData.pointerY}px;`"
         class="pointer">
      <div class="p_a">
        {{ `原始走势: ${(pageData.pointerA)?.toFixed(2)}` }}
      </div>
      <div class="p_b">
        {{ `模拟走势: ${(pageData.pointerB)?.toFixed(2)}` }}
      </div>
      <div class="index">
        {{ `开市分钟: ${(pageData.currenIndex)?.toFixed(0)}` }}
      </div>
    </div>
  </div>
</template>

<script setup>
import {computed, defineProps, onMounted, reactive, ref, watch} from "vue";

onMounted(() => {
  initLine()
})

const data = defineProps({
  listA: {
    type: Array,
    default: () => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  },
  listB: {
    type: Array,
    default: () => [1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5]
  },
  xAxios: {
    type: Array,
    default: () => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  },
  showXPoint: {
    type: Boolean,
    default: true
  },
  showYPoint: {
    type: Boolean,
    default: true
  }
});

const pageData = reactive({
  pointerA: 0,
  pointerB: 0,
  pointerX: 0,
  pointerY: 0,
  currenIndex: 0,
  pointerShow: false
});

const max = computed(() => {
  return Math.max(...data.listA, ...data.listB) - Math.min(...data.listA, ...data.listB)
})

const maxValue = computed(() => {
  return Math.max(...data.listA, ...data.listB)
})

const minValue = computed(() => {
  return Math.min(...data.listA, ...data.listB)
})


const cvsContainer = ref(null);

// 监听props中list的变化
watch(data, (newVal) => {
  //console.log('变化了')
  initLine()
},false)
const initLine = () => {

  const container = cvsContainer.value
  const width = container.offsetWidth
  const height = container.offsetHeight

  let canvas = document.getElementById('cvs');
  canvas.width = width
  canvas.height = height

  const ctx = canvas.getContext('2d')
  ctx.clearRect(0, 0, canvas.width, canvas.height);

// 设置 canvas 的显示尺寸
  canvas.style.width = '550px';  // 设置显示宽度
  canvas.style.height = '455px'; // 设置显示高度

  // 获取设备像素比
  let dpr = window.devicePixelRatio || 1;
// 设置 canvas 实际绘图尺寸
  canvas.width = 550 * dpr;  // 绘图区域宽度
  canvas.height = 455 * dpr; // 绘图区域高度

// 缩放绘图上下文，使其适应设备像素比,如果不缩放会导致规格和我们预期的不一样,因为上面的宽高根据像素比缩放过
  ctx.scale(dpr, dpr);
  // 绘制基础框架
  ctx.beginPath()
  ctx.moveTo(50, 50)
  ctx.lineTo(50, 400)
  ctx.lineTo(550, 400)
  ctx.stroke()


  // 画x刻度
  // x轴总长550,我们用数据总长度计算出每个刻度要画多长,这里刻度数量=数据长度,例如10cm想要分成2个刻度,那就是开头和结束两个刻度,就等于10个要分成一段也就是10/(2-1)
  const xScale = 500 / (data.xAxios.length - 1);
  const yScale = (max.value / 7);
  for (let i = 0; i <= 7; i++) {
    ctx.beginPath()
    ctx.strokeStyle = 'rgba(173,173,173,0.4)'
    ctx.lineWidth = 0.7
    ctx.moveTo(50, 400 - i * 50)
    ctx.lineTo(550, 400 - i * 50)
    // 画虚线
    ctx.setLineDash([4, 4, 1])
    ctx.stroke()
    const originVal = (i * yScale + minValue.value);
    let keepSize = 5 - (originVal.toString().split(".")[0].length);
    //console.log('keep:', keepSize)
    keepSize = Math.max(keepSize, 0)

    ctx.fillText(originVal.toFixed(keepSize), 80 - 5 * 14, 403 - i * 50,)
  }

  //  画折线A
  ctx.setLineDash([])
  // 这里使用定时器渲染,模拟动画
  ctx.beginPath()
  ctx.strokeStyle = 'rgba(190,15,56,1)'
  ctx.lineWidth = 1
  ctx.moveTo(50, 400 - (data.listA[0] - minValue.value) * 350 / max.value)
  for (let i = 1; i < data.listA.length; i++) {
    ctx.lineTo(50 + i * xScale, 400 - (data.listA[i] - minValue.value) * 350 / max.value)
  }
  ctx.stroke()

  //  画折线B
  ctx.setLineDash([])
  // 这里使用定时器渲染,模拟动画
  ctx.beginPath()
  ctx.strokeStyle = 'rgba(31,121,211,1)'
  ctx.lineWidth = 1
  ctx.moveTo(50, 400 - (data.listB[0] - minValue.value) * 350 / max.value)
  for (let i = 1; i < data.listB.length; i++) {
    ctx.lineTo(50 + i * xScale, 400 - (data.listB[i] - minValue.value) * 350 / max.value)
  }
  ctx.stroke()

  // 获取元素的边界信息
  const rect = canvas.getBoundingClientRect();
  // 绑定鼠标移动事件
  canvas.addEventListener('mousemove', (e) => {
    // 计算鼠标在元素内部的相对位置
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    // 打印出相对位置
    if ((x < 50 || x > 550) || (y < 50 || y > 400)) {
      if (pageData.pointerShow) {
        pageData.pointerShow = false
      }
      return
    }
    pageData.pointerShow = true
    if (x > 50) {
      const index = Math.round((x - 50) / xScale);
      pageData.currenIndex = Number(index.toFixed(0));
      // 四舍五入
      // 获取当前点的数据
      const valueA = data.listA[index];
      const valueB = data.listB[index];
      // 更新提示框的值
      pageData.pointerA = valueA
      pageData.pointerB = valueB
      pageData.pointerX = x + 15
      pageData.pointerY = y + 15
    }
  })
  canvas.addEventListener('mouseleave', () => {
    pageData.pointerShow = false;
  })
  canvas.addEventListener('mouseenter', () => {
    pageData.pointerShow = true;
  })
}
</script>

<style lang="scss" scoped>
.cvs-container {
  width: 100%;
  height: 100%;
  background-color: white;
  position: relative;

  .ver_line {
    height: calc(100% - 100px);
    width: 2px;
    position: absolute;;
    top: 50px;
    // 虚线
    border-left: 2px dashed #d0d0d0;
  }

  .hor_line {
    width: calc(550px - 50px);
    height: 2px;
    position: absolute;;
    left: 50px;
    top: 0;
    // 虚线
    border-top: 2px dashed #cecece;
  }

  .canvas {
    position: absolute;
    left: 0;
    top: 0;
  }

  .pointer {
    position: absolute;
    padding: 20px;
    height: 50px;
    font-size: 14px;
    border-radius: 10px;
    background-color: rgba(244, 244, 244, 0.95);
    display: flex;
    justify-content: center;
    align-items: start;
    color: white;
    box-shadow: 3px 3px 6px rgba(0, 0, 10, .07);
    flex-direction: column;
    z-index: 1000;
    gap: 2px;

    div{
      white-space: nowrap;
    }
    .p_a {
      color: rgba(190, 15, 56, 0.7);
    }

    .p_b {
      color: rgba(31, 121, 211, .7);
    }
    .index{
      color: #02c73f;
    }
  }
}

</style>

